home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / SHOWFILE / WIND.WRK < prev   
Encoding:
Text File  |  2001-02-09  |  20.7 KB  |  1,032 lines

  1. /* wind.c */
  2.  
  3.  
  4. #include "obdefs.h"
  5. #include "gemdefs.h"
  6. #include "osbind.h"
  7. #include "mydefs.h"
  8. #include "wind.h"
  9. #include "addr.h"
  10. #include "error.h"
  11. #include "errno.h"
  12. #include "stdio.h"
  13. #include "stat.h"
  14.  
  15.  
  16. #define APP_INFO ""
  17. #define APP_NAME "Window Example"
  18. #define MAX(X,Y)    ( (X) > (Y) ? (X) : (Y) )
  19. #define MIN(X,Y)    ( (X) < (Y) ? (X) : (Y) )
  20.  
  21.  
  22. /* AES (windows and messages) related variables */
  23. int gl_hchar;        /* height of system font (pixels) */
  24. int gl_wchar;        /* width of system font (pixels) */
  25. int gl_wbox;        /* width of box able to hold system font */
  26. int gl_hbox;        /* height of box able to hold system font */
  27.  
  28. extern int gl_apid;
  29.  
  30. int phys_handle;    /* physical workstation handle */
  31. int handle;        /* virtual workstation handle */
  32. int wi_handle;        /* window handle */
  33.  
  34. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  35. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  36. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  37.  
  38. char *sbuf[512];
  39. int keycode;        /* keycode returned by event-keyboard */
  40. int mx, my;        /* mouse x and y pos. */
  41. int butdown;        /* button state tested for, UP/DOWN */
  42. int ret;        /* dummy return variable */
  43. int hidden;        /* current state of cursor */
  44. int contrl[12];
  45. int intin[128];
  46. int ptsin[128];
  47. int intout[128];
  48. int ptsout[128];    /* storage wasted for idiotic bindings */
  49. int work_in[11];    /* Input to GSX parameter array */
  50. int work_out[57];    /* Output from GSX parameter array */
  51. int pxyarray[10];    /* input point array */
  52. int msg[8];            /* message buffer */
  53. long toptx;            /* the top line of text currently in the window */
  54. long leftx;            /* the most left text in the window */
  55. int cellw, cellh, chspcw, chspch;    /* size of default character font */
  56. char *dbuff;        //* a buffer of a file */
  57. long *list;            /* the list of pointer of lines in a file */
  58. long nrow;            /* total number of lines in a file */
  59. int running;
  60. long maxln;            /* the longest of text in a file */
  61.  
  62. /*
  63.  * Top level;
  64.  * we get control from the desktop.
  65.  */
  66. main()
  67. {
  68.  
  69.  
  70.     appl_init();
  71.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  72.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  73.     open_vwork();
  74.     /*
  75.     hw_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  76.     */
  77.  
  78.     if (!rsrc_load(RESOURCEFILE))    {
  79.         errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  80.         goto doneit;
  81.     }
  82.     
  83.     /* Get all addresses of dialogues from resource file */
  84.     if (getalladdr() != OK) {
  85.         errs("[2][|", RESOURCEFILE, "][ EXIT ]");
  86.         goto doneit;
  87.     }
  88.  
  89.     ARROW_MOUSE;
  90.     menu_bar(menubar, 1);
  91.     running = TRUE;
  92.     while(running)    {
  93.         domulti();
  94.     }
  95.     menu_bar(menubar, 0);
  96.  
  97. doneit:
  98.     wind_delete(wi_handle);
  99.     Mfree(dbuff);
  100.     Mfree(list);
  101.     v_clsvwk(handle);
  102.     appl_exit();
  103. }
  104.  
  105. doopenwd()
  106. {
  107.  
  108.     int done = FALSE;
  109.     long slidsiz;
  110.     int hsldsiz;
  111.     DMABUFFER dma;
  112.     int status, i, tmpy, tmpx, fp;
  113.     char *sbuff, *tem;
  114.     /*
  115.     int attrib[4];
  116.     */
  117.     long *tmp;
  118.     int deskx, desky, deskw, deskh;
  119.  
  120.  
  121.     wi_handle=wind_create(0xFFFF, xdesk, ydesk, wdesk, hdesk);
  122.     wind_set(wi_handle, WF_INFO, APP_INFO, 0, 0);
  123.     wind_set(wi_handle, WF_NAME, APP_NAME, 0, 0);
  124.     wind_open(wi_handle, xdesk+30, ydesk+30, wdesk/2, hdesk/2);
  125.     wind_get(wi_handle, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  126.  
  127.     toptx = 0;        /* start top line of text */
  128.     leftx = 0;
  129.  
  130. /*
  131.     vst_alignment(handle, 0, 5, &done, &done);     set text alignment
  132. */
  133.  
  134. /*
  135.     wind_calc(0, 0xFFFF,
  136.                 gl_wchar*5, gl_hchar*5, gl_wchar*TCOLS+4, hwork*SROWS+4,
  137.                 &xwork, &ywork, &wwork, &hwork);
  138. */
  139.     /* set the window to that size */
  140. /*
  141.     wind_set(wi_handle, WF_CURRXYWH, 
  142.                         xwork, ywork, wwork, hwork);
  143. */
  144.  
  145.  
  146. /*
  147.     find the work area
  148.  
  149.     wind_get(wi_handle, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  150. */
  151.  
  152.  
  153.     /* read the file into buffer */
  154.  
  155.     Fsetdta(&dma);
  156.     if ((status = Fsfirst("c:\\fmt.c", 0xF7)) != 0)
  157.         fatal(status, "fmt.c");
  158.     if ((sbuff = Malloc(dma.d_fsize + 1)) == NULL)
  159.         exit(1);
  160.     if ((dbuff = Malloc(dma.d_fsize + 1000)) == NULL)
  161.         exit(1);
  162.     if ((fp = Fopen("c:\\fmt.c", "rb")) < 0)    {
  163.         Mfree(sbuff);
  164.         Mfree(dbuff);
  165.         fatal(fp, "cannot open input file");
  166.     }
  167.     if ((status=Fread(fp, (long)dma.d_fsize, sbuff)) < 0)    {
  168.         Mfree(sbuff);
  169.         Mfree(dbuff);
  170.         fatal(status, "fmt.c");
  171.     }
  172.     nrow = findsiz(sbuff);
  173.     list = Malloc(nrow);
  174.     converstr(list, sbuff, dbuff);
  175.     /*
  176.     vqm_attributes(wi_handle, attrib);
  177.     */
  178.     /* find slider size and set it */
  179.     slidsiz = (1000*(hwork-5)/gl_hchar) / nrow; 
  180.     hsldsiz = (1000*wwork/gl_wchar) / maxln;
  181.     wind_set(wi_handle, WF_VSLSIZE, (int)slidsiz, 0, 0, 0);
  182.     wind_set(wi_handle, WF_HSLSIZE, hsldsiz, 0, 0, 0);
  183.     do_redraw(xwork, ywork, wwork, hwork);
  184.     /*
  185.     wind_update(1);
  186.     tmpy = ywork+3;
  187.     toptx = 0;
  188.     while (tmpy < hwork+3)    {
  189.         tmpy += 4*attrib[3]/5;
  190.         v_gtext(wi_handle, xwork, tmpy, *list++);
  191.         toptx++;
  192.     }
  193.     wind_update(0);
  194.     ARROW_MOUSE;
  195.     */
  196.     /*
  197.  
  198.     do
  199.     {
  200.         evnt_mesage(msg);     get message 
  201.         done = deal_msg();     and handle them
  202.     } while(!done);
  203.  
  204.     wind_delete(wi_handle);
  205.     Mfree(sbuff);
  206.     Mfree(dbuff);
  207.     Mfree(list);
  208.     */
  209.     Mfree(sbuff);
  210.  
  211. }
  212.  
  213. deal_msg()
  214. {
  215.     int done = FALSE;
  216.     long tmp;
  217.     GRECT box;
  218.  
  219.     box.g_x = xwork;
  220.     box.g_y = ywork;
  221.     box.g_h = hwork;
  222.     box.g_w = wwork;
  223.  
  224.     switch(msg[0])    {
  225.  
  226.         case  WM_REDRAW:        /* do the redraw by call redraw routine */
  227.             redraw(msg[3], (GRECT *)&msg[4]);
  228.             break;
  229.  
  230.         case  WM_TOPPED:        /* if topped, send to top */
  231.             wind_set(msg[3], WF_TOP, 0, 0, 0, 0);
  232.             break;
  233.  
  234.         case  WM_SIZED:            /* if sized, check for min size, then resize */
  235.             msg[6] = MAX(msg[6], gl_wchar*8);
  236.             msg[7] = MAX(msg[7], gl_hchar*4);
  237.             wind_set(msg[3], WF_CURRXYWH, msg[4], msg[5], msg[6], msg[7]);
  238.             redraw(msg[3], (GRECT *)&msg[4]);
  239.             break;
  240.  
  241.         case  WM_MOVED:            /* if moved, make sure the window stays on the
  242.                                    desktop */
  243.             if (msg[4] + msg[6] > xdesk + wdesk)    {
  244.                 msg[4] = xdesk + wdesk - msg[6];
  245.             } 
  246.             if (msg[5] + msg[7] > ydesk + hdesk)    {
  247.                 msg[5] = ydesk + hdesk - msg[7];
  248.             }
  249.             wind_set(msg[3], WF_CURRXYWH, msg[4], msg[5], msg[6], msg[7]);
  250.             break;
  251.  
  252.         case  WM_FULLED:        /* if fulled, do toggle routine */
  253.             toggle(msg[3]);
  254.             break;
  255.  
  256.         case  WM_CLOSED:        /* if closed, set flag */
  257.             wind_close(msg[3]);
  258.             done = TRUE;
  259.             break;
  260.  
  261.         case  WM_VSLID:            /* slide bar was dragged */
  262.             tmp = msg[4] * (nrow-hwork/gl_hchar) / 1000;    /* calc toptx */
  263.             toptx = tmp;
  264.             redraw(wi_handle, &box);    /* redraw window */
  265.             mvslide();
  266.             break;
  267.         case  WM_HSLID:            /* slide bar was dragged */
  268.             break;
  269.  
  270.         case  WM_ARROWED:
  271.             switch (msg[4])    {
  272.                 case 0:    /* page up */
  273.                     toptx = MAX(0, toptx-hwork/gl_hchar);
  274.                     break;
  275.  
  276.                 case 1:    /* page down */
  277.                     toptx = MIN(nrow-hwork/gl_hchar, toptx+hwork/gl_hchar);
  278.                     break;
  279.  
  280.                 case 2:    /* row up */
  281.                     toptx = MAX(0, toptx-1);
  282.                     break;
  283.  
  284.                 case 3:    /* row down */
  285.                     toptx = MIN(nrow-hwork/gl_hchar, toptx+1);
  286.                     break;
  287.  
  288.                 default:
  289.                     break;
  290.             }
  291.             redraw(wi_handle, &box);    /* redraw window */
  292.             mvslide();
  293.             break;
  294.  
  295.         default:
  296.             break;
  297.     }
  298.  
  299.     return(done);
  300. }
  301.  
  302. /* this function do the WM_FULLED message */
  303.  
  304. toggle(wh)        
  305. int wh;
  306. {
  307.  
  308.     GRECT prv, cur, full;
  309.  
  310.     /* get the previous, current, and the full size of windows */
  311.     wind_get(wh, WF_PREVXYWH, &prv.g_x, &prv.g_y, &prv.g_w, &prv.g_h);
  312.     wind_get(wh, WF_CURRXYWH, &cur.g_x, &cur.g_y, &cur.g_w, &cur.g_h);
  313.     wind_get(wh, WF_FULLXYWH, &full.g_x, &full.g_y, &full.g_w, &full.g_h);
  314.  
  315.     /* if it is full size, change it to previous unless that was full also */
  316.  
  317.     if (((cur.g_x == full.g_x) &&
  318.          (cur.g_y == full.g_y) &&
  319.          (cur.g_w == full.g_w) &&
  320.          (cur.g_h == full.g_h)) &&
  321.              ((prv.g_x != full.g_x) ||
  322.               (prv.g_y != full.g_y) ||
  323.               (prv.g_w != full.g_w) ||
  324.               (prv.g_h != full.g_h)))     {
  325.         wind_set(wh, WF_CURRXYWH, prv.g_x, prv.g_y, prv.g_w, prv.g_h);
  326.         wind_get(wh, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  327.         prv.g_x = xwork;
  328.         prv.g_y = ywork;
  329.         prv.g_h = hwork;
  330.         prv.g_w = wwork;
  331.         clrbox(&prv);
  332.         /*
  333.         redraw(wh, &prv);
  334.         xwork = prv.g_x;
  335.         ywork = prv.g_y;
  336.         hwork = prv.g_h;
  337.         wwork = prv.g_w;
  338.         redwmsg(wh, &prv);        
  339.         */
  340.     } else {
  341.         wind_set(wh, WF_CURRXYWH, full.g_x, full.g_y, full.g_w, full.g_h);
  342.         wind_get(wh, WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  343.         full.g_x = xwork;
  344.         full.g_y = ywork;
  345.         full.g_w = wwork;
  346.         full.g_h = hwork;
  347.         do_redraw(full.g_x, full.g_y, full.g_w, full.g_h);
  348.         /*
  349.         redraw(wh, &full);        
  350.         do_redraw(full.g_x, full.g_y, full.g_w, full.g_h);
  351.         xwork = full.g_x;
  352.         ywork = full.g_y;
  353.         hwork = full.g_h;
  354.         wwork = full.g_w;
  355.         redraw(wh, &prv);        
  356.         */
  357.     }
  358. }
  359.  
  360. /* send redraw message to the window */
  361.  
  362. redwmsg(wh, r)
  363.  
  364. int wh;
  365. GRECT *r;
  366.  
  367. {
  368.     int msg[8];
  369.  
  370.     msg[0] = WM_REDRAW;
  371.     msg[1] = gl_apid;
  372.     msg[2] = 0;
  373.     msg[3] = wh;
  374.     msg[4] = r->g_x;
  375.     msg[5] = r->g_y;
  376.     msg[6] = r->g_w;
  377.     msg[7] = r->g_h;
  378.     xwork = r->g_x;
  379.     ywork = r->g_y;
  380.     hwork = r->g_h;
  381.     wwork = r->g_w;
  382.     appl_write(gl_apid, 16, &msg);
  383. }
  384.  
  385.  
  386. /* redraw the window */
  387.  
  388. redraw(msg, dbox)    
  389.  
  390. int msg;        /* window handle from msg[3] */
  391. GRECT *dbox;    /* pointer to the redraw rectangle */
  392.  
  393. {  
  394.  
  395.     GRECT wdrct;    /* the current window rectangle in rect list */ 
  396.  
  397.     hide_mouse();        /* turn off mouse */
  398.     wind_update(BEG_UPDATE);    /* lock screen */
  399.     wind_get
  400.         (msg, WF_FIRSTXYWH, &wdrct.g_x, &wdrct.g_y, &wdrct.g_w, &wdrct.g_h);
  401.     while (wdrct.g_w && wdrct.g_h)    {    /* while it is not the last one */
  402.         if (overlap(dbox, &wdrct))    { /*check to see if this one is damaged*/ 
  403.             setclip(&wdrct, msg);          /*if it is, set clip rectangle*/
  404.             /*
  405.             clrbox(&wdrct);
  406.             */
  407.             writewd(msg);                /* redraw the window */
  408.             vs_clip(msg, FALSE, (int *)&wdrct);
  409.         }
  410.         wind_get
  411.           (msg, WF_NEXTXYWH, &wdrct.g_x, &wdrct.g_y, &wdrct.g_w, &wdrct.g_h);
  412.     }
  413.     wind_update(END_UPDATE);    /* unlock screen */
  414.     show_mouse();        /* turn on mouse */
  415.  
  416. }
  417.  
  418. /* draw and display the window */
  419.  
  420. writewd(wh)
  421. int wh;
  422. {
  423.     int i, j;
  424.     int temp[4];
  425.  
  426.     /*
  427.     temp[0] = xwork;
  428.     temp[1] = ywork;
  429.     temp[2] = xwork + wwork - 1;
  430.     temp[3] = ywork + hwork - 1;
  431.     v_bar(handle, temp);
  432.     */
  433.     j = nrow - toptx;    /* number of line left */
  434.     for (i=0; i < hwork/gl_hchar; i++)    {
  435.         if (j >= i)    {
  436.             v_gtext(wh, xwork+2-(int)leftx*gl_wchar, 
  437.                             gl_hchar*i + ywork+6, *(list+toptx+i));
  438.         } else    {
  439.             break;
  440.         }
  441.     }
  442.     /*
  443.     toptx += i;
  444.     */
  445.  
  446. }
  447.  
  448.  
  449. /* move the slider to match top text */
  450.  
  451. mvslide(wh, msg)
  452. int wh;
  453. int msg;
  454. {
  455.     int cslide, nslide, flag;
  456.     long tmp;
  457.  
  458.     if (msg > 3)    {    /* do the horizontal move */
  459.         flag = WF_HSLIDE;
  460.         tmp = 1000*leftx/(maxln-wwork/gl_wchar);
  461.     } else {            /* do the vertical move */
  462.         flag = WF_VSLIDE;
  463.         tmp = 1000*toptx/(nrow-(hwork-5)/gl_hchar);
  464.     }
  465.     wind_get(wh, flag, &cslide, &nslide, &nslide, &nslide);
  466.     if ((nslide=tmp) != cslide)    {
  467.         wind_set(wh, flag, nslide, 0, 0, 0);
  468.     }
  469. }
  470.  
  471.  
  472. /* set clip to specified rectangle */
  473. setclip(p, wh)    
  474. GRECT *p;
  475. int wh;
  476.  
  477. {
  478.     int ptr[4];
  479.  
  480.     grect_conv(p, ptr);
  481.     vs_clip(wh, TRUE, ptr);
  482. }
  483.  
  484. clrbox(r)
  485. GRECT *r;
  486.  
  487. {
  488.     int p[4];
  489.  
  490.     grect_conv(r, &p);
  491.     vsf_interior(handle, 1);
  492.     vsf_color(handle, 0);
  493.     v_bar(handle, &p);
  494. }
  495.  
  496. grect_conv(r, ar)
  497. GRECT *r;
  498. int *ar;
  499. {
  500.     *ar++ = r->g_x;
  501.     *ar++ = r->g_y;
  502.     *ar++ = r->g_x + r->g_w - 1;
  503.     *ar   = r->g_y + r->g_h - 1;
  504. }
  505.  
  506. /* compute overlap of two rectangles */
  507.  
  508. overlap(r1, r2)
  509. GRECT *r1, *r2;
  510. {
  511.     int x, y, x1, y1;
  512.  
  513.     x = MAX(r2->g_x, r1->g_x);
  514.     y = MAX(r2->g_y, r1->g_y);
  515.     r2->g_w = MIN(r2->g_x + r2->g_w, r1->g_x + r1->g_w) - x;
  516.     r2->g_h = MIN(r2->g_y + r2->g_h, r1->g_y + r1->g_h) - y;
  517.     r2->g_x = x;
  518.     r2->g_y = y;
  519.     return((r2->g_w > 0) && (r2->g_h > 0));
  520. }
  521.  
  522.  
  523. fatal(error, msg)
  524. int error; char *msg;
  525. {
  526.     errno = -error;
  527.     perror(msg);
  528.     exit(1);
  529. }
  530.  
  531.  
  532. findsiz(buf)
  533. char *buf;
  534. {
  535.     int n=0;
  536.  
  537.     while (*buf)    {
  538.         while (*buf != 0x0D)    {
  539.             buf++;
  540.         }
  541.         n++;
  542.         buf += 2;
  543.     }
  544.     return (n);
  545. }
  546.  
  547. converstr(list, sbuff, dbuff)
  548. long *list;
  549. char *sbuff;
  550. char *dbuff;
  551. {
  552.  
  553.     long *tmp;
  554.     char *sptr, *dptr;
  555.     int i=0, j=0;
  556.     int width=0;
  557.  
  558.  
  559.     tmp = list;
  560.     maxln = 0;
  561.     *tmp++ = dbuff;
  562.     sptr = sbuff;
  563.     dptr = dbuff;
  564.     if (*sptr == 0x0D)    { /* the first line is the blank line */
  565.         *dptr++ = 0x20;
  566.         *dptr++ = 0x00;
  567.         sptr += 2;
  568.         *tmp++ = dptr;
  569.     } 
  570.     while (*sptr)    {
  571.         while ((*sptr != 0x09) && ((*dptr++ = *sptr) != 0x0D))    {
  572.             i++;
  573.             sptr++;
  574.         }
  575.         switch(*sptr)    {
  576.             case 0x09:        /* it is a tab char */
  577.                 sptr++;
  578.                 j = 4 - i%4;    /* calculate how many space should be */
  579.                 i += j;
  580.                 switch(j)    {
  581.                     case 4:
  582.                         *dptr++ = 0x20;
  583.                         *dptr++ = 0x20;
  584.                         *dptr++ = 0x20;
  585.                         *dptr++ = 0x20;
  586.                         break;
  587.                     case 3:
  588.                         *dptr++ = 0x20;
  589.                         *dptr++ = 0x20;
  590.                         *dptr++ = 0x20;
  591.                         break;
  592.                     case 2:
  593.                         *dptr++ = 0x20;
  594.                         *dptr++ = 0x20;
  595.                         break;
  596.                     case 1:
  597.                         *dptr++ = 0x20;
  598.                         break;
  599.                     default:
  600.                         break;
  601.                 }
  602.                 width += i;    /* the width the line */
  603.                 break;
  604.             case 0x0D:        /* it is a carriage return char */
  605.                 sptr++;
  606.                 if (*(sptr-2) == 0x0A) {/* it is a blank line */
  607.                     *(dptr-1) = 0x20;
  608.                     *dptr++ = 0x00;
  609.                 } else {
  610.                     *(dptr-1) = 0x00;
  611.                 }
  612.                 *tmp++ = dptr;
  613.                 sptr++;
  614.                 width += i;
  615.                 maxln = MAX(maxln, width);
  616.                 width = 0;
  617.                 break;
  618.             default:
  619.                 break;
  620.         }
  621.         i = 0;
  622.     }
  623. }
  624. /*
  625.  
  626. converstr(list, buff)
  627. long *list;
  628. char *buff;
  629. {
  630.  
  631.     long *tmp;
  632.     char *ptr;
  633.  
  634.     *list = buff;
  635.     tmp = list;
  636.     ptr = buff;
  637.     if (*ptr == 0x0D)    {  the first line is the blank line
  638.         *ptr++ = 0x20;
  639.         *ptr++ = 0x00;
  640.         *tmp++ = ptr;
  641.     } else     {
  642.         tmp++;
  643.     }
  644.     while (*ptr)    {
  645.         while (*ptr != 0x0D)    {
  646.             ptr++;
  647.         }
  648.         if ((*(ptr-1) == 0x00) || (*(ptr-1) == 0x0A)) { it is a blank line
  649.             *ptr++ = 0x20;
  650.             *ptr++ = 0x00;
  651.             *tmp++ = ptr;
  652.             continue;
  653.         }
  654.         *ptr = 0x00;
  655.         ptr += 2;
  656.         *tmp++ = ptr;
  657.     }
  658. }
  659.  
  660. */
  661.  
  662. /*
  663.  * Get a single event, process it, and return.
  664.  *
  665.  */
  666. domulti(){
  667.     int event;
  668.     long tmp;
  669.     GRECT box;
  670.     int prvw, prvh;
  671.  
  672.     box.g_x = xwork;
  673.     box.g_y = ywork;
  674.     box.g_h = hwork;
  675.     box.g_w = wwork;
  676.     
  677.     event = evnt_multi(MU_MESAG, 1,1,butdown, 0,0,0,0,0, 0,0,0,0,0,
  678.                         msg,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  679.  
  680.     if (event & MU_MESAG) {
  681.         wind_update(TRUE);
  682.     switch (msg[0]) {
  683.         case  WM_REDRAW:        /* do the redraw by call redraw routine */
  684.             redraw(msg[3], &box);
  685.             break;
  686.  
  687.         case  WM_TOPPED:        /* if topped, send to top */
  688.             wind_set(msg[3], WF_TOP, 0, 0, 0, 0);
  689.             wind_get(msg[3], WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  690.             box.g_x = xwork;
  691.             box.g_y = ywork;
  692.             box.g_h = hwork;
  693.             box.g_w = wwork;
  694.             do_redraw(xwork, ywork, wwork, hwork);
  695.             break;
  696.  
  697.         case  WM_SIZED:            /* if sized, check for min size, then resize */
  698.             msg[6] = MAX(msg[6], gl_wchar*8);
  699.             msg[7] = MAX(msg[7], gl_hchar*4);
  700.             wind_set(msg[3], WF_CURRXYWH, msg[4], msg[5], msg[6], msg[7]);
  701.             wind_get(msg[3], WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  702.             prvh    = box.g_h;
  703.             prvw    = box.g_w;
  704.             box.g_x = xwork;
  705.             box.g_y = ywork;
  706.             box.g_h = hwork;
  707.             box.g_w = wwork;
  708.             do_redraw(xwork, ywork, wwork, hwork);
  709.             if ((prvh >= hwork) && (prvw >= wwork))    {
  710.                 redraw(msg[3], &box);
  711.             }
  712.             /*
  713.             redraw(msg[3], &box);
  714.             msg[0] = 0;
  715.             redwmsg(msg[3], (GRECT *)msg[4]);
  716.             */
  717.             break;
  718.  
  719.         case  WM_MOVED:            /* if moved, make sure the window stays on the
  720.                                    desktop */
  721.             if (msg[4] + msg[6] > xdesk + wdesk)    {
  722.                 msg[4] = xdesk + wdesk - msg[6];
  723.             } 
  724.             if (msg[5] + msg[7] > ydesk + hdesk)    {
  725.                 msg[5] = ydesk + hdesk - msg[7];
  726.             }
  727.             wind_set(msg[3], WF_CURRXYWH, msg[4], msg[5], msg[6], msg[7]);
  728.             wind_get(msg[3], WF_WORKXYWH, &xwork, &ywork, &wwork, &hwork);
  729.             box.g_x = xwork;
  730.             box.g_y = ywork;
  731.             box.g_h = hwork;
  732.             box.g_w = wwork;
  733.             do_redraw(xwork, ywork, wwork, hwork);
  734.             redraw(msg[3], &box);
  735.             break;
  736.  
  737.         case  WM_FULLED:        /* if fulled, do toggle routine */
  738.             toggle(msg[3]);
  739.             break;
  740.  
  741.         case  WM_CLOSED:        /* if closed, set flag */
  742.             wind_close(msg[3]);
  743.             break;
  744.  
  745.         case  WM_VSLID:            /* slide bar was dragged */
  746.             tmp = msg[4] * (nrow-(hwork-5)/gl_hchar) / 1000;    /* calc toptx */
  747.             toptx = tmp;
  748.             clrbox(&box);
  749.             redraw(msg[3], &box);    /* redraw window */
  750.             mvslide(msg[3], 0);
  751.             break;
  752.  
  753.         case  WM_HSLID:            /* slide bar was dragged */
  754.             if (wwork <= maxln*gl_wchar)        {
  755.                 tmp = msg[4] * (maxln-wwork/gl_wchar) / 1000; 
  756.                 leftx = tmp;
  757.                 clrbox(&box);
  758.                 redraw(msg[3], &box);
  759.                 mvslide(msg[3], 4);
  760.             }
  761.             break;
  762.  
  763.         case  WM_ARROWED:
  764.             switch (msg[4])    {
  765.                 case 0:    /* page up */
  766.                     toptx = MAX(0, toptx-(hwork-5)/gl_hchar);
  767.                     break;
  768.  
  769.                 case 1:    /* page down */
  770.                      toptx = MIN(nrow-(hwork-5)/gl_hchar, 
  771.                                             toptx+(hwork-5)/gl_hchar);
  772.                     break;
  773.  
  774.                 case 2:    /* row up */
  775.                     toptx = MAX(0, toptx-1);
  776.                     break;
  777.  
  778.                 case 3:    /* row down */
  779.                     toptx = MIN(nrow-(hwork-5)/gl_hchar, toptx+1);
  780.                     break;
  781.  
  782.                 case 4:    /* page left */
  783.                     if (wwork <= maxln*gl_wchar)        {
  784.                         leftx = MAX(0, leftx-wwork/gl_wchar);
  785.                     }
  786.                     break;
  787.                 case 5:    /* page right */
  788.                     if (wwork <= maxln*gl_wchar)        {
  789.                          leftx = MIN(maxln-wwork/gl_wchar, 
  790.                                             leftx+wwork/gl_wchar);
  791.                     }
  792.                     break;
  793.                 case 6:    /* column left */
  794.                     if (wwork <= maxln*gl_wchar)        {
  795.                         leftx = MAX(0, leftx-1);
  796.                     }
  797.                     break;
  798.                 case 7:    /* column right */
  799.                     if (wwork <= maxln*gl_wchar)        {
  800.                         leftx = MIN(maxln-wwork/gl_wchar, leftx+1);
  801.                     }
  802.                     break;
  803.                 default:
  804.                     break;
  805.             }
  806.             clrbox(&box);
  807.             redraw(msg[3], &box);      /* redraw window */
  808.             mvslide(msg[3], msg[4]);
  809.             break;
  810.  
  811.         case MN_SELECTED:
  812.             BEE_MOUSE;
  813.         switch(msg[3]) {
  814.             case WINDOW:
  815.                 switch (msg[4]) {
  816.                     case OPENWD:
  817.                         doopenwd();
  818.                         break;
  819.                     case RDFILE:
  820.                         dordfile();
  821.                         break;
  822.                     default:        
  823.                         break;
  824.                 }
  825.                 break;
  826.  
  827.             case MNFILE:
  828.                 switch (msg[4]) {
  829.                     case FIQUIT:
  830.                     running = 0;
  831.                     break;
  832.  
  833.                         default:
  834.                         break;
  835.                 }
  836.                 break;
  837.             
  838.             case MNDESK:
  839.             /*
  840.             if(msg[4] == DABOUT) {
  841.                 strcpy(abtdial[ABVERSN].ob_spec, "Version 5.00");
  842.                  abtdial[ABOK].ob_state = NORMAL;
  843.                 execform(abtdial);
  844.             }
  845.             */
  846.             break;        /* "cannot happen" */
  847.         }
  848.  
  849.         menu_tnormal(menubar, msg[3], 1);    /* back to normal */
  850.         ARROW_MOUSE;
  851.         break;
  852.         
  853.         case WM_NEWTOP:
  854.             wind_set(wi_handle, WF_TOP, 0, 0, 0, 0);
  855.             break;
  856.  
  857.  
  858.         default:
  859.         break;
  860.     }
  861.     wind_update(FALSE);
  862.     }
  863. }
  864.  
  865. dordfile()
  866. {
  867. ;
  868. }
  869.  
  870.  
  871. /*
  872.  * Open virtual workstation.
  873.  *
  874.  */
  875. open_vwork()
  876. {
  877.     int i;
  878.  
  879.     for (i = 0; i < 10;)
  880.     work_in[i++] = 1;
  881.     work_in[10] = 2;
  882.     handle = phys_handle;
  883.     v_opnvwk(work_in, &handle, work_out);
  884. }
  885.  
  886.  
  887. /*
  888.  * Find and redraw all clipping rectangles
  889.  *
  890.  */
  891. do_redraw(xc, yc, wc, hc)
  892. int xc, yc, wc, hc;
  893. {
  894.     GRECT t1, t2;
  895.     int temp[4];
  896.  
  897.     hide_mouse();
  898.     t2.g_x=xc;
  899.     t2.g_y=yc;
  900.     t2.g_w=wc;
  901.     t2.g_h=hc;
  902.     vsf_interior(handle, 1);
  903.     vsf_color(handle, 0);
  904.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  905.     while (t1.g_w && t1.g_h) {
  906.     if (rc_intersect(&t2, &t1)) {
  907.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  908.         temp[0] = xwork;
  909.         temp[1] = ywork;
  910.         temp[2] = xwork + wwork - 1;
  911.         temp[3] = ywork + hwork - 1;
  912.         v_bar(handle, temp);
  913.     }
  914.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  915.     }
  916.  
  917.     show_mouse();
  918. }
  919.  
  920.  
  921. /*
  922.  * Hide the mouse.
  923.  *
  924.  */
  925. hide_mouse()
  926. {
  927.     if (!hidden) {
  928.     graf_mouse(M_OFF, 0L);
  929.     hidden = TRUE;
  930.     }
  931. }
  932.  
  933.  
  934. /*
  935.  * Show the mouse.
  936.  *
  937.  */
  938. show_mouse() 
  939. {
  940.     if (hidden) {
  941.     graf_mouse(M_ON, 0L);
  942.     hidden = FALSE;
  943.     }
  944. }
  945.  
  946.  
  947. /*
  948.  * Set clipping rectangle.
  949.  *
  950.  */
  951. set_clip(x, y, w, h)
  952. int x, y, w, h;
  953. {
  954.     int clip[4];
  955.  
  956.     clip[0] = x;
  957.     clip[1] = y;
  958.     clip[2] = x + w;
  959.     clip[3] = y + h;
  960.     vs_clip(handle, 1, clip);
  961. }
  962.  
  963.  
  964. /*
  965.  * "Execute" form,
  966.  * return thingy that caused the exit.
  967.  *
  968.  */
  969. execform(tree)
  970. OBJECT tree[];
  971. {
  972.     int thingy;
  973.  
  974.     ARROW_MOUSE;
  975.     dsplymsg(tree);
  976.     thingy = form_do(tree, 0);
  977.     erasemsg();
  978.     BEE_MOUSE;
  979.     return thingy;
  980. }
  981.  
  982.  
  983. /*
  984.  *  Display a dialogue box on the screen.
  985.  *    Input:
  986.  *        tree - object tree for dialogue box to be displayed.
  987.  *    Output:
  988.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  989.  */
  990. dsplymsg(tree)
  991. OBJECT *tree;
  992. {
  993.     form_center(tree,&lx, &ly, &formw, &formh);
  994.  
  995.     /*
  996.     sx = lx + formw / 2;
  997.     sy = ly + formh / 2;
  998.     */
  999.     
  1000.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  1001.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  1002. }
  1003.  
  1004.  
  1005. /*
  1006.  *  Erase a dialogue box from the screen.
  1007.  *    Input:
  1008.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  1009.  */
  1010. erasemsg()
  1011. {
  1012.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  1013. }
  1014.  
  1015.  
  1016.  
  1017. /*
  1018.  *  Make a long (4-byte) random.
  1019.  */ 
  1020. long
  1021. longrandom()
  1022. {
  1023.     long pattern;
  1024.     
  1025.     pattern = Random();
  1026.     pattern <<= 16;
  1027.     pattern ^= Random();
  1028.     
  1029.     return (pattern);
  1030. }
  1031.  
  1032.